package com.example.jserrorresolver.service;

import com.example.jserrorresolver.config.SourceMapProperties;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Service;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
@RequiredArgsConstructor
public class SourceMapResolverService {

    private final SourceMapProperties properties;
    private final ResourceLoader resourceLoader;

    /**
     * 解析JavaScript错误堆栈
     */
    public String resolveErrorStack(String stackTrace, String customSourceMapDir) throws IOException, InterruptedException {
        // 确定SourceMap目录
        String sourceMapDir = (customSourceMapDir != null && !customSourceMapDir.trim().isEmpty()) 
                ? customSourceMapDir 
                : properties.getDirectory();
        
        // 获取Node.js脚本路径
        String nodeScriptPath = getResolvedNodeScriptPath();
        
        // 构建命令
        List<String> command = new ArrayList<>();
        command.add(properties.getNodeExecutablePath());
        command.add(nodeScriptPath);
        command.add(sourceMapDir);
        
        log.info("执行命令: {}", String.join(" ", command));
        
        // 启动进程
        ProcessBuilder processBuilder = new ProcessBuilder(command);
        processBuilder.redirectErrorStream(true);
        Process process = processBuilder.start();
        
        // 写入堆栈信息
        try (OutputStream os = process.getOutputStream()) {
            os.write(stackTrace.getBytes(StandardCharsets.UTF_8));
            os.flush();
        }
        
        // 读取结果
        String result;
        try (InputStream is = process.getInputStream()) {
            result = IOUtils.toString(is, StandardCharsets.UTF_8);
        }
        
        // 等待进程完成
        int exitCode = process.waitFor();
        if (exitCode != 0) {
            throw new RuntimeException("Node.js脚本执行失败，退出码: " + exitCode);
        }
        
        return result;
    }
    
    /**
     * 获取Node.js脚本的实际路径
     */
    private String getResolvedNodeScriptPath() throws IOException {
        if (properties.getNodeScriptPath().startsWith("classpath:")) {
            Resource resource = resourceLoader.getResource(properties.getNodeScriptPath());
            if (resource.exists()) {
                return resource.getFile().getAbsolutePath();
            } else {
                throw new FileNotFoundException("Node.js脚本未找到: " + properties.getNodeScriptPath());
            }
        }
        return properties.getNodeScriptPath();
    }
}
